"""
Copyright 2008 Olivier Belanger

This file is part of Ounk.

Ounk is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Ounk is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Ounk.  If not, see <http://www.gnu.org/licenses/>.

Logistic:
The logistic map equation is used to model population growth over time. This particular
equation, though simple, provides a very rich set of behaviours for different values of 
the parameter 'a' when iterated.
arg 1: Constant value 'a' in the range 0 -> 4.
arg 2: initial state between 0 -> 1.

Henon:
The Henon map is a discrete-time dynamical system. It is one of the most studied examples 
of dynamical systems that exhibit chaotic behavior. The Henon map takes a point (x, y) in 
the plane and maps it to a new point.
arg1: constant a (default to 1.4)
arg2: constant b (default to 0.3)
arg3: x initial value (default to 0.1)
arg4: y initial value (default to 0.1)
"""

class Logistic:
    def __init__( self, constant, initial ):
        self.a = constant
        self.x = initial
        
    def next( self ):
        """Method to call a new value from a generator objet."""
        self.x = self.a * self.x * (1. - self.x)
        return self.x

    def changeConstant(self, constant):
        """Change the constant values used in the logistic or henon equation.

logistic:
constant = x_new_constant_value

henon:
constant = (a, b) tuple

--- PARAMETERS ---

constant : New constant value to be used in the logistic equation or (a,b) tuple used in the henon equation.

* See logistic or henon page for an example.
"""
        self.a = constant

    def changeInitial(self, initial):
        """Reset the initial value used in the logistic equation to an arbitrary value. henon equation needs a tuple (x,y).

logistic:
initial = new_initial_value

henon:
initial = (x, y) tuple

--- PARAMETERS ---

initial : New initial value to be used in the logistic equation or (x,y) tuple used in the henon equation.

* See logistic or henon page for an example.
"""
        self.x = initial

class Henon:
    def __init__( self, a, b, x, y ):
        self.a = a
        self.b = b
        self.x = x
        self.y = y
        
    def next( self ):
        """Method to call a new value from a generator objet."""
        new_x = self.y + 1. - (self.a * (self.x * self.x))
        new_y = self.b * self.x
        self.x, self.y = new_x, new_y
        return self.x, self.y

    def changeConstant(self, constant):
        """Change the constant value used in the logistic or henon equation.

logistic:
constant = x_new_constant_value

henon:
constant = (a, b) tuple

--- PARAMETERS ---

constant : New constant value to be used in the logistic equation or (a,b) tuple used in the henon equation.

* See logistic or henon page for an example.
"""
        self.a = constant[0]
        self.b = constant[1]

    def changeInitial(self, initial):
        """Reset the initial value used in the logistic equation to an arbitrary value. henon equation needs a tuple (x,y).

logistic:
initial = new_initial_value

henon:
initial = (x, y) tuple

--- PARAMETERS ---

initial : New initial value to be used in the logistic equation or (x,y) tuple used in the henon equation.

* See logistic or henon page for an example.
"""
        self.x = initial[0]
        self.y = initial[1]
